using System;
using System.Collections.Generic;
using System.Reflection;
using AutoAim.Config;
using HarmonyLib;
using Unity.VisualScripting;
using UnityEngine;

namespace AutoAim
{
    public class ModBehaviour : Duckov.Modding.ModBehaviour
    {
        private readonly HashSet<CharacterMainControl> _enemies = new HashSet<CharacterMainControl>();
        private int _frameSkip = 1;
        private Harmony? _harmony;

        private static ModBehaviour? _modInstance;
        public static ModBehaviour Instance => _modInstance ??= FindObjectOfType<ModBehaviour>();

        private AutoAimConfig _config;

        // 添加一个状态（用于热键切换）
        public bool IsAutoAimEnabled => _config.activationMode != AimActivationMode.ToggleWithHotkey || _toggleEnabled;
        private bool _toggleEnabled;

        public AutoAimConfig GetAutoAimConfig()
        {
            return _config;
        }

        protected override void OnAfterSetup()
        {
            // 加载配置
            _config = ConfigManager.LoadConfig();
            ConfigManager.SetupModConfig(_config);
            ConfigManager.LoadConfigFromModConfig(_config);

            if (_modInstance == null) _modInstance = this;
            if (_harmony != null) return;

            _harmony = new Harmony("Braycep.AutoAim");
            _harmony.PatchAll(Assembly.GetExecutingAssembly());
        }

        protected override void OnBeforeDeactivate()
        {
            ConfigManager.OnBeforeDeactivate(_config);

            _modInstance = null;
            _harmony?.UnpatchAll();
        }

        private void Update()
        {
            // 动态帧率控制: 目标50FPS时跳帧
            _frameSkip = (1f / Time.deltaTime) > Instance._config.frameSkipThreshold ? 1 : 2;
            if (Time.frameCount % _frameSkip != 0) return;

            // 每30帧清理一次无效敌人
            if (Time.frameCount % Instance._config.cacheCleanupIntervalFrames == 0)
            {
                _enemies.RemoveWhere(IsInvalidEnemy);
            }
        }

        // [HarmonyPatch(typeof(Health), nameof(Health.Hurt))]
        // public static class HealthPatch
        // {
        //     [HarmonyPrefix]
        //     public static bool Prefix(Health __instance, DamageInfo damageInfo, ref bool __result)
        //     {
        //         if (!__instance.IsMainCharacterHealth) return true;
        //         __result = true;
        //         return false;
        //     }
        // }

        // 1. 核心补丁: 团队设置时自动注册 (避免每帧查找敌人)
        [HarmonyPatch(typeof(CharacterMainControl), "SetTeam")]
        public static class SetTeamPatch
        {
            [HarmonyPostfix]
            public static void Postfix(CharacterMainControl __instance, Teams _team)
            {
                // 把敌人加入内存HashSet中，加快后续查找
                if (IsHostileAI(_team))
                {
                    Instance._enemies.Add(__instance);
                }
            }
        }

        // 2. 核心补丁: 敌人销毁时自动清理缓存
        [HarmonyPatch(typeof(CharacterMainControl), "OnDestroy")]
        public static class OnDestroyPatch
        {
            [HarmonyPrefix]
            public static void Prefix(CharacterMainControl __instance)
            {
                // 将敌人移除
                Instance._enemies.Remove(__instance);
            }
        }

        // 4. 主瞄准补丁: 使用缓存
        [HarmonyPatch(typeof(InputManager), "SetAimInputUsingMouse")]
        public static class SetAimInputUsingMousePatch
        {
            // ===== 反射缓存 =====
            private static readonly FieldInfo? AimScreenPoint =
                typeof(InputManager)
                    .GetField("aimScreenPoint", BindingFlags.Instance | BindingFlags.NonPublic);

            private static readonly FieldInfo? AimCacheField =
                typeof(InputManager).GetField("_aimMousePosCache", BindingFlags.Instance | BindingFlags.NonPublic);

            private static readonly FieldInfo? SyncFlagField =
                typeof(InputManager).GetField("aimMousePosFirstSynced", BindingFlags.Instance | BindingFlags.NonPublic);

            [HarmonyPrefix]
            public static void Prefix(InputManager __instance, ref Vector2 mouseDelta)
            {
                var player = CharacterMainControl.Main;
                if (player == null) return;

                var instance = Instance;
                if (!instance._config.ShouldActivate(player)) return;

                if (instance._config.aimMode == AimMode.HardLock)
                {
                    // 锁定模式
                    float maxDist = instance._config.GetLockDistance(player.GetGun());
                    CharacterMainControl? nearestEnemy = null;
                    float nearestSqr = maxDist * maxDist;

                    foreach (var enemy in Instance._enemies)
                    {
                        if (IsInvalidEnemy(enemy)) continue;

                        var sqrDist = (enemy.transform.position - player.transform.position).sqrMagnitude;
                        if (sqrDist < nearestSqr)
                        {
                            nearestSqr = sqrDist;
                            nearestEnemy = enemy;
                        }
                    }

                    // 锁定敌人
                    if (nearestEnemy == null)
                    {
                        return;
                    }

                    Vector2 targetScreenPos =
                        LevelManager.Instance.GameCamera.renderCamera.WorldToScreenPoint(
                            instance._config.GetTargetPosition(nearestEnemy));

                    AimCacheField?.SetValue(__instance, targetScreenPos);
                    SyncFlagField?.SetValue(__instance, true); // 确保不重新 sync

                    mouseDelta = Vector2.zero;

                    AimScreenPoint?.SetValue(__instance, targetScreenPos);
                }
                else if (instance._config.aimMode == AimMode.Adsorption)
                {
                    // --- 吸附逻辑 (修正后): 寻找离准星最近的敌人 ---

                    // 1. 获取当前玩家的准星屏幕位置作为参考点
                    var currentAimPosObj = AimScreenPoint?.GetValue(__instance);
                    if (currentAimPosObj == null) return;
                    Vector2 currentAimPos = (Vector2)currentAimPosObj;

                    // 2. 初始化目标和最小屏幕距离
                    CharacterMainControl? nearestEnemyToCrosshair = null;
                    float minScreenDistance = float.MaxValue;
                    float worldLockDistance = instance._config.GetLockDistance(player.GetGun());

                    // 3. 遍历所有敌人，寻找屏幕上离准星最近的那个
                    foreach (var enemy in Instance._enemies)
                    {
                        if (IsInvalidEnemy(enemy)) continue;

                        // 优化: 如果敌人在世界空间中太远，直接跳过，不进行屏幕坐标转换
                        if ((enemy.transform.position - player.transform.position).sqrMagnitude >
                            worldLockDistance * worldLockDistance)
                        {
                            continue;
                        }

                        // 获取敌人在屏幕上的位置
                        Vector2 enemyScreenPos =
                            LevelManager.Instance.GameCamera.renderCamera.WorldToScreenPoint(
                                instance._config.GetTargetPosition(enemy));

                        // 计算准星与目标的屏幕距离
                        float screenDistance = Vector2.Distance(currentAimPos, enemyScreenPos);

                        // 如果这个敌人比之前记录的更近，则更新为新目标
                        if (screenDistance < minScreenDistance)
                        {
                            minScreenDistance = screenDistance;
                            nearestEnemyToCrosshair = enemy;
                        }
                    }

                    // 4. 如果找到了在吸附范围内的目标，则施加引力
                    if (nearestEnemyToCrosshair != null && minScreenDistance <= instance._config.adsorptionRange)
                    {
                        // 计算引力强度
                        float strength = instance._config.adsorptionStrength;
                        if (instance._config.adsorptionFalloff == AdsorptionFalloff.Linear)
                        {
                            strength *= (1.0f - (minScreenDistance / instance._config.adsorptionRange));
                        }

                        // 计算需要施加的额外输入（引力）
                        Vector2 targetScreenPos =
                            LevelManager.Instance.GameCamera.renderCamera.WorldToScreenPoint(
                                instance._config.GetTargetPosition(nearestEnemyToCrosshair));
                        Vector2 pullDirection = targetScreenPos - currentAimPos;

                        // 修改 mouseDelta，将引力叠加到玩家的原始输入上
                        mouseDelta += pullDirection * strength;
                    }
                }
            }
        }

        // 工具方法: 检查缓存中的敌人是否有效
        private static bool IsInvalidEnemy(CharacterMainControl enemy)
        {
            return !enemy ||
                   // !enemy.isActiveAndEnabled ||
                   enemy.IsDestroyed() ||
                   enemy.Health.IsDead;
        }

        // 保持不变的逻辑
        [HarmonyPatch(typeof(CharacterMainControl), "GunScatterMultiplier", MethodType.Getter)]
        public static class GunScatterMultiplierPatch
        {
            [HarmonyPostfix]
            public static void Postfix(ref float __result) => __result *= Instance._config.gunScatterMultiplier;
        }

        private static bool IsHostileAI(Teams team)
        {
            var isHostileAI = team == Teams.scav ||
                              team == Teams.lab ||
                              team == Teams.wolf ||
                              team == Teams.usec ||
                              team == Teams.bear;
            return isHostileAI;
        }

        public static void Log(object msg)
        {
            if (Instance._config.writeLog)
            {
                Debug.Log($"[{DateTime.Now:MM-dd HH:mm:ss}] ${msg}");
            }
        }

        private void OnHotkeyPressed()
        {
            if (_config.activationMode != AimActivationMode.ToggleWithHotkey) return;
            _toggleEnabled = !_toggleEnabled;
        }
    }
}